import QRCode from 'qrcode-generator'

import type { QrItem } from '@/utils/download'

const width = 400
const height = 450

interface WorkerTask {
  item: QrItem
  index: number
  offscreen: any
  icon: CanvasImageSource
}

self.onmessage = async (e: MessageEvent<WorkerTask>) => {
  try {
    const { item, index, offscreen, icon } = e.data
    const blob = await generateInWorker(item, offscreen, icon)

    // 使用 Transferable 对象提升性能
    self.postMessage(
      {
        type: 'complete',
        data: {
          blob: blob,
          fileName: item.fileName
        }
      }
      // [blob]
    )

    // 报告进度
    self.postMessage({
      type: 'progress',
      data: {
        processed: index + 1,
        total: (self as any).totalTasks
      }
    })
  } catch (err) {
    self.postMessage({
      type: 'error',
      data: {
        error: `生成失败: ${(err as Error).message}`
      }
    })
  }
}

async function generateInWorker(
  item: QrItem,
  offscreen: any,
  icon: CanvasImageSource
): Promise<Blob> {
  // 使用 OffscreenCanvas 替代 DOM 操作
  // const offscreen = OffscreenCanvas(300, 350)
  offscreen.width = width
  offscreen.height = height
  const ctx = offscreen.getContext('2d')!

  ctx.fillStyle = 'white'
  ctx.fillRect(0, 0, 400, 450)

  // 生成二维码
  const qr = QRCode(0, 'M')
  qr.addData(item.url)
  qr.make()

  // 生成二维码矩阵
  const matrix = qr.getModuleCount()
  // const canvas = new OffscreenCanvas(size, size)
  // const ctx = canvas.getContext('2d')

  // 手动绘制二维码
  const cellSize = width / matrix
  ctx.fillStyle = 'white'
  ctx.fillRect(0, 0, width, width)
  ctx.fillStyle = 'black'

  for (let i = 0; i < matrix; i++) {
    for (let j = 0; j < matrix; j++) {
      if (qr.isDark(i, j)) {
        ctx.fillRect(j * cellSize, i * cellSize, cellSize, cellSize)
      }
    }
  }

  ctx.drawImage(
    icon,
    width / 2 - (width * 0.2) / 2,
    width / 2 - (width * 0.2) / 2,
    width * 0.2,
    width * 0.2
  )

  // 绘制文字
  ctx.font = '20px Arial'
  ctx.textAlign = 'center'
  ctx.fillStyle = '#000'
  ctx.fillText(item.text, width / 2, height - 20)

  // 转 Blob
  return await offscreen.convertToBlob({
    type: 'image/png',
    quality: 0.9
  })
}
